#include "shared_object.h"
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
using namespace std;
using namespace thrust;

void *cpu(void* input){
	SharedObject* shared_object = (SharedObject*) input;

	vector<int> gpu_result;

	vector<int> cpu_vec(5,1);

	for(int i = 1; i < 10; i++){
		// retrieve
		shared_object->get_gpu_result(gpu_result);
		cout << "cpu has: ";
		for(int k = 0; k < gpu_result.size(); k++) cout << gpu_result[k] << " ";
		cout << endl;

		// compute
		for(int k = 0; k < cpu_vec.size(); k++) cpu_vec[k] = 2*i+1;

		// set result for gpu
		shared_object->set_cpu_result(cpu_vec);
		cout << "cpu finish set object" << endl;
	}
	return NULL;
}

void *gpu(void* input){
	SharedObject* shared_object = (SharedObject*) input;

	host_vector<int> cpu_result;
	// first round
	device_vector<int> gpu_vec(3,0);
	shared_object->set_gpu_result(gpu_vec);

	for(int i = 1; i < 10; i++){
		// compute
		for(int k = 0; k < gpu_vec.size(); k++) gpu_vec[k] = 2*i;
		
		// retrieve
		shared_object->get_cpu_result(cpu_result);
		cout << "gpu has: ";
		for(int k = 0; k < cpu_result.size(); k++) cout << cpu_result[k] << " ";
		cout << endl;

		// set result for cpu
		shared_object->set_gpu_result(gpu_vec);
		cout << "gpu finish set object" << endl;
	}

	return NULL;
}

int main(){
	cout << "succeed" << endl;

	pthread_t thread1, thread2;

	SharedObject* shared_object = new SharedObject();

	pthread_create( &thread1, NULL, &cpu, (void*)shared_object);
	pthread_create( &thread2, NULL, &gpu, (void*)shared_object);

	pthread_join( thread1, NULL);
	pthread_join( thread2, NULL);


	delete shared_object;
	return 0;
}